﻿using GN.Pay.TradeChannel.Configure;
using GN.Pay.TradeChannel.UnionPay.Request;
using GN.Pay.TradeChannel.UnionPay.Response;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GN.Pay.TradeChannel.UnionPay
{
    [Serializable]
    public abstract class UnionPayServiceBase : ATradeChannel<IDictionary<string, string>>
    {
        protected readonly UnionPayConfigure channelConfigure;
        public UnionPayServiceBase()
        {
            channelConfigure = new UnionPayConfigure(this);
        }
        public override ITradeChannelConfigure ChannelConfigure
        {
            get
            {
                return channelConfigure;
            }
        }

        /// <summary>
        /// 获取提供者全称
        /// </summary>
        public sealed override string ChannelProvider
        {
            get
            {
                return "中国银联股份有限公司";
            }
        }


        public override Type TradeChannelConfigureInfoType
        {
            get
            {
                return typeof(UnionPayConfigureInfo);
            }
        }

        private static IChannel TempChannel = TradeChannelInfo.Create("UnionPay", "银联");


        /// <summary>
        /// 获取付款的订单号
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static string GetPayOrderNo(IDictionary<string, string> message)
        {
            if (message == null || message.Count == 0)
            {
                return null;
            }
            NotifyResponse response = new NotifyResponse(message);
            var entity = response.ToEntity<PayNotifyResponseEntity>();
            return entity.orderId;
        }


        /// <summary>
        /// 获取退款批次号
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static string GetRefundNo(IDictionary<string, string> message)
        {
            if (message == null || message.Count == 0)
            {
                return null;
            }
            NotifyResponse response = new NotifyResponse(message);
            var entity = response.ToEntity<RefundNotifyResponseEntity>();
            return entity.orderId;
        }

        /// <summary>
        /// 订单付款通知响应
        /// </summary>
        /// <param name="message">消息</param>
        public PayNotifyResponseEntity OrderPayNotifyResponse(IDictionary<string, string> message)
        {
            NotifyResponse response = new NotifyResponse(message);
            if (!response.SignVeryfy(this, this.channelConfigure))
            {
                this.ThrowChannelValidationException("银联支付支付通知验签失败");
            }
            try
            {
                var entity = response.ToEntity<PayNotifyResponseEntity>();                
                return entity;
            }
            catch (Exception e)
            {
                throw this.ThrowChannelValidationException("银联支付支付通知数据格式出错:" + e.Message);
            }
        }

        /// <summary>
        /// 银联即时到账支付通知处理
        /// </summary>
        /// <param name="sercice"></param>
        /// <param name="message"></param>
        public sealed override void OrderPayNotify(INotifyService sercice,
            IDictionary<string, string> message)
        {
            var entity = OrderPayNotifyResponse(message);
            if (entity.IsSuccess())
            {
                var result = entity.ToPayResult(this);
                if (result != null)
                {
                    sercice.OrderPayNotify(result);
                }
            }
        }

        public override void OrderRefundNotify(INotifyService sercice, IDictionary<string, string> message)
        {
            NotifyResponse response = new NotifyResponse(message);
            if (!response.SignVeryfy(this, this.channelConfigure))
            {
                this.ThrowChannelValidationException("银联退款通知验签失败");
            }
            try
            {
                var entity = response.ToEntity<RefundNotifyResponseEntity>();
                var result = entity.ToRefundResult(this);
                sercice.OrderRefundNotify(result);

            }
            catch (Exception e)
            {
                this.ThrowChannelValidationException("银联退款通知数据格式出错:" + e.Message);
            }
        }

        public override ITradeOrderQueryResult OrderSingleQuery(DateTime queryDate, string orderNo, string tradeNo)
        {
            if (string.IsNullOrWhiteSpace(orderNo))
            {
                TradeChannelExceptionUtils.ThrowClientRequestException(this.ChannelId, "查询订单时，订单号不能为空");
            }
            var req = new QueryRequest(this, channelConfigure, orderNo);
            var res = req.Build();
            if (!res.IsSuccess())
            {
                return null;
            }
            if (!res.SignVeryfy())
            {
                TradeChannelExceptionUtils.ThrowClientRequestException(this.ChannelId, "验证未通过");
            }
            return res.ToResult();
        }

        public override ITradeRefundApplyResult RefundApply(IRefundApplyInfo apply)
        {
            var config = this.channelConfigure;
            var request = RefundRequest.CreateRefundRequest(this, apply, config);
            var response = request.Build(this, config, apply);
            if (!response.SignVeryfy())
            {
                TradeChannelExceptionUtils.ThrowClientRequestException(this.ChannelId, "验证未通过");
            }
            return response.ToResult();
        }
        public sealed override string PayNotifyResponse(bool isSuccess)
        {
            if (isSuccess)
            {
                return "success";
            }
            return "fail";
        }

        public sealed override string RefundNotifyResponse(bool isSuccess)
        {
            if (isSuccess)
            {
                return "success";
            }
            return "fail";
        }
    }
}
